home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
drdobbs
/
1991
/
05
/
d_flat
/
listbox.c
< prev
next >
Wrap
Text File
|
1991-02-18
|
5KB
|
182 lines
/* ------------- listbox.c ------------ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dflat.h"
static void near writeselection(WINDOW, int, int, RECT *);
static void near change_selection(WINDOW, int);
static int near selection_in_window(WINDOW, int);
int ListBoxProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
{
int rtn;
static int py = -1;
int my = (int) p2 - GetTop(wnd);
if (my >= wnd->wlines-wnd->wtop)
my = wnd->wlines - wnd->wtop;
switch (msg) {
case CREATE_WINDOW:
rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2);
wnd->selection = -1;
return rtn;
case ADDTEXT:
p2 = wnd->wlines == wnd->selection;
break;
case CLEARTEXT:
wnd->selection = -1;
break;
case SCROLL:
rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2);
if (!selection_in_window(wnd, wnd->selection)) {
if (p1)
PostMessage(wnd, LB_SELECTION, wnd->selection+1, FALSE);
else
PostMessage(wnd, LB_SELECTION, wnd->selection-1, FALSE);
}
else
writeselection(wnd, wnd->selection, TRUE, NULL);
return rtn;
case KEYBOARD:
if (WindowMoving || WindowSizing)
break;
switch ((int) p1) {
case UP:
if (wnd->selection > 0) {
if (wnd->selection == wnd->wtop) {
writeselection(wnd, wnd->selection, FALSE, NULL);
--wnd->selection;
rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2);
PostMessage(wnd, LB_SELECTION, wnd->selection, FALSE);
}
else {
int newsel = wnd->selection-1;
if (wnd->wlines == ClientHeight(wnd))
while (*TextLine(wnd, newsel) == LINE)
--newsel;
PostMessage(wnd, LB_SELECTION, newsel, FALSE);
}
}
return TRUE;
case DN:
if (wnd->selection < wnd->wlines-1) {
if (wnd->selection == wnd->wtop+ClientHeight(wnd)-1) {
writeselection(wnd, wnd->selection, FALSE, NULL);
wnd->selection++;
rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2);
PostMessage(wnd, LB_SELECTION, wnd->selection, FALSE);
}
else {
int newsel = wnd->selection+1;
if (wnd->wlines == ClientHeight(wnd))
while (*TextLine(wnd, newsel) == LINE)
newsel++;
PostMessage(wnd, LB_SELECTION, newsel, FALSE);
}
}
return TRUE;
case PGUP:
case PGDN:
rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2);
PostMessage(wnd, LB_SELECTION, wnd->wtop, FALSE);
return rtn;
case HOME:
rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2);
PostMessage(wnd, LB_SELECTION, 0, FALSE);
return rtn;
case END:
rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2);
PostMessage(wnd, LB_SELECTION, wnd->wlines-1, FALSE);
return rtn;
case '\r':
if (wnd->selection != -1) {
WINDOW pwnd = GetParent(wnd);
SendMessage(wnd, LB_SELECTION, wnd->selection, TRUE);
SendMessage(pwnd, LB_CHOOSE, wnd->selection, 0);
}
return TRUE;
default:
break;
}
break;
case BUTTON_RELEASED:
py = -1;
break;
case LEFT_BUTTON:
if (!(WindowMoving || WindowSizing)) {
RECT rc = ClientRect(wnd);
if (!InsideRect(p1, p2, rc))
break;
if (my != py) {
int newsel = wnd->wtop+my-1;
if (*TextLine(wnd, newsel) != LINE)
SendMessage(wnd, LB_SELECTION, newsel, TRUE);
py = my;
}
return TRUE;
}
break;
case DOUBLE_CLICK:
BaseWndProc(LISTBOX, wnd, msg, p1, p2);
if (!(WindowMoving || WindowSizing))
SendMessage(GetParent(wnd), LB_CHOOSE, wnd->selection, 0);
return TRUE;
case LB_SETSELECTION:
change_selection(wnd, (int) p1);
return TRUE;
case LB_SELECTION: {
WINDOW pwnd = GetParent(wnd);
CLASS class = GetClass(pwnd);
change_selection(wnd, (int) p1);
if (class != LISTBOX && DerivedClass(class) != LISTBOX)
SendMessage(GetParent(wnd), LB_SELECTION, wnd->selection, 0);
return TRUE;
}
case LB_CURRENTSELECTION:
return wnd->selection;
case LB_GETTEXT:
if ((int)p2 != -1) {
char *cp1 = (char *)p1;
char *cp2 = TextLine(wnd, (int)p2);
while (cp2 && *cp2 && *cp2 != '\n')
*cp1++ = *cp2++;
*cp1 = '\0';
}
return TRUE;
case PAINT:
if (isVisible(wnd)) {
rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2);
writeselection(wnd, wnd->selection, TRUE, (RECT *)p1);
return rtn;
}
break;
default:
break;
}
return BaseWndProc(LISTBOX, wnd, msg, p1, p2);
}
static int near selection_in_window(WINDOW wnd, int sel)
{
return (wnd->wlines && sel >= wnd->wtop && sel < wnd->wtop+ClientHeight(wnd));
}
static void near writeselection(WINDOW wnd, int sel, int reverse, RECT *rc)
{
if (selection_in_window(wnd, sel))
WriteTextLine(wnd, rc, sel-wnd->wtop, reverse);
}
static void near change_selection(WINDOW wnd, int sel)
{
if (sel != wnd->selection) {
writeselection(wnd, wnd->selection, FALSE, NULL);
wnd->selection = sel;
writeselection(wnd, sel, TRUE, NULL);
}
}